<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Troubleshooting</title>
</head>
<body>

<h2>Troubleshooting</h2>

While preparing a configuration for processing your code, you may bump into a
few problems. The following sections discuss some common issues and solutions:
<ul>
<li><a href="#processing">Problems while processing</a>
<li><a href="#afterprocessing">Unexpected observations after processing</a>
<li><a href="#preverifying">Problems while preverifying for Java Micro
    Edition</a>
<li><a href="#runtime">Problems at run-time</a>
</ul>

<a name="processing">&nbsp;</a>
<h2>Problems while processing</h2>

ProGuard may print out some notes and non-fatal warnings:

<dl>
<dt><a name="dynamicalclass"><b>Note: ... calls '(...)Class.forName(variable).newInstance()'</b></a></dt>

<dd>ProGuard lists all class casts of dynamically created class instances,
    like "<code>(MyClass)Class.forName(variable).newInstance()</code>".
    Depending on your application, you may need to keep the mentioned classes
    with an option like "<code>-keep class MyClass</code>", or their
    implementations with an option like "<code>-keep class * implements
    MyClass</code>". You can switch off these notes by specifying the
    <code>-dontnote</code> option.</dd>

<dt><a name="dynamicalclassmember"><b>Note: ... accesses a field/method '...' dynamically</b></a></dt>

<dd>ProGuard lists a number of constructs like
    "<code>.getField("myField")</code>". Depending on your application, you
    may need to figure out where the mentioned class members are defined and
    keep them with an option like "<code>-keep class MyClass { MyFieldType
    myField; }</code>". You can switch off these notes by specifying the
    <code>-dontnote</code> option.</dd>

<dt><a name="duplicateclass"><b>Note: duplicate definition of program/library class</b></a></dt>

<dd>Your program jars or library jars contain multiple definitions of the
    listed classes. ProGuard continues processing as usual, only considering
    the first definitions. The warning may be an indication of some problem
    though, so it's advisable to remove the duplicates. A convenient way to do
    so is by specifying filters on the input jars or library jars. You can
    switch off these notes by specifying the <code>-dontnote</code>
    option.</dd>

<dt><a name="duplicatezipentry"><b>Warning: can't write resource ... Duplicate zip entry</b></a></dt>

<dd>Your input jars contain multiple resource files with the same name.
    ProGuard continues copying the resource files as usual, skipping any files
    with previously used names. Once more, the warning may be an indication of
    some problem though, so it's advisable to remove the duplicates. A
    convenient way to do so is by specifying filters on the input jars. There
    is no option to switch off these warnings.</dd>

</dl>
<p>

ProGuard may terminate when it encounters parsing errors or I/O errors, or
some more serious warnings:

<dl>
<dt><a name="unresolvedclass"><b>Warning: can't find superclass or interface</b></a></dt>

<dd>If there are unresolved references to superclasses or interfaces, you most
    likely forgot to specify an essential library. All libraries that are
    referenced by your code should be specified, including the Java run-time
    library. For specifying libraries, use the <code>-libraryjars</code>
    option.
    <p>
    If the class that is reported as missing is a non-public library class,
    you should specify the <code>-dontskipnonpubliclibraryclasses</code>
    option. A common example is the class
    <code>java.util.zip.ZipConstants</code>, which is used as an interface
    class in some public classes, even though it is only package visible (in
    this case, the warning could also be ignored, because the class is not a
    fundamental part of the class hierarchy).
    <p>
    If you're missing a library and you're absolutely sure it isn't used
    anyway, you can try your luck with the <code>-ignorewarnings</code>
    option, or even the <code>-dontwarn</code> option.</dd>

<dt><a name="unresolvedclassmember"><b>Warning: can't find referenced field/method</b></a></dt>

<dd>If there are unresolved references to class members in input classes, your
    class files are most likely inconsistent. Possibly, some class file didn't
    get recompiled properly, or some class file was left behind after its
    source file was removed. Try removing all class files, recompiling them,
    zipping them up, and running ProGuard again.
    <p>
    If the class member that is reported as missing is actually implemented in
    a non-public library class, you should specify the
    <code>-dontskipnonpubliclibraryclasses</code> option. A common example is
    the method <code>setLength(int)</code> in the public class
    <code>java.lang.StringBuilder</code>. This method is actually defined in
    the package visible superclass
    <code>java.lang.AbstractStringBuilder</code>, which ProGuard ignores by
    default.
    <p>
    If your program classes reside in the same packages as library classes,
    and refer to their package visible class members, then you should specify
    the <code>-dontskipnonpubliclibraryclassmembers</code> option.</dd>

<dt><a name="unresolvedenclosingmethod"><b>Warning: can't find enclosing class/method</b></a></dt>

<dd>If there are unresolved references to classes that are defined inside
    methods in your input, once more, your class files are most likely
    inconsistent. Possibly, some class file didn't get recompiled properly, or
    some class file was left behind after its source file was removed. Try
    removing all class files, recompiling them, zipping them up, and running
    ProGuard again.</dd>

<dt><a name="unexpectedclass"><b>Warning: class file ... unexpectedly contains class ...</b></a></dt>

<dd>The given class file contains a definition for the given class, but the
    directory name of the file doesn't correspond to the package name of the
    class. ProGuard will accept the class definition, but the current
    implementation will not write out the processed version. Please make sure
    your input classes are packaged correctly. Notably, class files that are
    in the <code>WEB-INF/classes</code> directory in a war should be packaged
    in a jar and put in the <code>WEB-INF/lib</code> directory. If you don't
    mind these classes not being written to the output, you can specify the
    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
    option.</dd>

<dt><a name="mappingconflict1"><b>Warning: ... is not being kept as ..., but remapped to ...</b></a></dt>

<dd>There is a conflict between a <code>-keep</code> option in the
    configuration, and the mapping file, in the obfuscation step. The given
    class name or class member name can't be kept by its original name, as
    specified in the configuration, but it has to be mapped to the other given
    name, as specified in the mapping file. You should adapt your
    configuration or your mapping file to remove the conflict. Alternatively,
    if you're sure the renaming won't hurt, you can specify the
    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
    option.</dd>

<dt><a name="mappingconflict2"><b>Warning: field/method ... can't be mapped to ...</b></a></dt>

<dd>There is a conflict between some new program code and the mapping file, in
    the obfuscation step. The given class member can't be mapped to the given
    name, because it would conflict with another class member that is already
    being mapped to the same name. This can happen if you are performing
    incremental obfuscation, applying an obfuscation mapping file from an
    initial obfuscation step. For instance, some new class may have been added
    that extends two existing classes, introducing a conflict in the name
    space of its class members. If you're sure the class member receiving
    another name than the one specified won't hurt, you can specify the
    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
    option. Note that you should always use the
    <code>-useuniqueclassmembernames</code> option in the initial obfuscation
    step, in order to reduce the risk of conflicts.</dd>

<dt><a name="keep"><b>Error: You have to specify '-keep' options</b></a></dt>

<dd>You either forgot to specify <code>-keep</code> options, or you mistyped
    the class names. ProGuard has to know exactly what you want to keep: an
    application, an applet, a servlet, a midlet,..., or any combination of
    these. Without the proper seed specifications, ProGuard would shrink,
    optimize, or obfuscate all class files away.</dd>


<dt><a name="macosx"><b>Error: Can't read [</b>...<b>/lib/rt.jar] (No such file or directory)</b> (in MacOS X)</a></dt>

<dd>In MacOS X, the run-time classes may be in a different place than on most
    other platforms. You'll then have to adapt your configuration, replacing
    the path <code>&lt;java.home&gt;/lib/rt.jar</code> by
    <code>&lt;java.home&gt;/../Classes/classes.jar</code>.</dd>

</dl>
<p>

Should ProGuard crash while processing your application:

<dl>
<dt><a name="outofmemoryerror"><b>OutOfMemoryError</b></a></dt>

<dd>You can try increasing the heap size of the Java virtual machine (with the
    usual <code>-Xms</code> and <code>-Xmx</code> options). You can also
    reduce the amount of memory that ProGuard needs by removing unnecessary
    library jars from your configuration, or by filtering out unused library
    packages and classes. Remember that only classes or interfaces that are
    extended or implemented by classes in your input jars are required.</dd>

<dt><a name="stackoverflowerror"><b>StackOverflowError</b></a></dt>

<dd>This error may occur when optimizing very complex methods on Windows
    (surprisingly, not so easily on Linux). You can always work around it by
    using ProGuard's <code>-dontoptimize</code> option. In theory, increasing
    the stack size of the Java virtual machine (with the usual
    <code>-Xss</code> option) should help too. In practice however, the
    <code>-Xss</code> setting doesn't have any effect on the main thread, due
    to <a
    href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4362291">Sun Bug
    #4362291</a>. As a result, this solution will only work when running
    ProGuard in a different thread, e.g. from its GUI.</dd>

<dt><a name="otherwise"><b>Otherwise...</b></a></dt>

<dd>Maybe your class files are corrupt. See if recompiling them and trying
    again helps. If not, please report the problem, preferably with the
    simplest example that causes ProGuard to crash.</dd>

</dl>
<p>

<a name="afterprocessing">&nbsp;</a>
<h2>Unexpected observations after processing</h2>

If ProGuard seems to run fine, but your processed code doesn't look right,
there might be a couple of reasons:

<dl>
<dt><a name="disappearingclasses"><b>Disappearing classes</b></a></dt>

<dd>If you are working on Windows and it looks like some classes have
    disappeared from your output, you should make sure you're not writing
    your output class files to a directory (or unpacking the output jar). On
    platforms with case-insensitive file systems, such as Windows, unpacking
    tools often let class files with similar lower-case and upper-case names
    overwrite each other. If you really can't switch to a different operating
    system, you could consider using ProGuard's
    <code>-dontusemixedcaseclassnames</code> option.
    <p>
    Also, you should make sure your class files are in directories that
    correspond to their package names. ProGuard will read misplaced class
    files, but it will currently not write their processed versions. Notably,
    class files that are in the <code>WEB-INF/classes</code> directory in a
    war should be packaged in a jar and put in the <code>WEB-INF/lib</code>
    directory.</dd>

<dt><a name="notkept"><b>Classes or class members not being kept</b></a></dt>

<dd>If ProGuard is not keeping the right classes or class members, make
    sure you are using fully qualified class names. If the package name of
    some class is missing, ProGuard won't match the elements that you might be
    expecting. It may help to double-check for typos too. You can use the
    <code>-printseeds</code> option to see which elements are being kept
    exactly.
    <p>
    If you are using marker interfaces to keep other classes, the marker
    interfaces themselves are probably being removed in the shrinking step.
    You should therefore always explicitly keep any marker interfaces.</dd>

<dt><a name="notobfuscated"><b>Variable names not being obfuscated</b></a></dt>

<dd>If the names of the local variables and parameters in your obfuscated code
    don't look obfuscated, because they suspiciously resemble the names of
    their types, it's probably because the decompiler that you are using is
    coming up with those names. ProGuard's obfuscation step does remove the
    original names entirely, unless you explicitly keep the
    <code>LocalVariableTable</code> or <code>LocalVariableTypeTable</code>
    attributes.</dd>

</dl>

<a name="preverifying">&nbsp;</a>
<h2>Problems while preverifying for Java Micro Edition</h2>

If ProGuard seems to run fine, but the external preverifier subsequently
produces errors, it's usually for a single reason:

<dl>
<dt><a name="invalidclassexception1"><b>InvalidClassException</b>,
    <b>class loading error</b>, or
    <b>verification error</b></a></dt>

<dd>If you get any such message from the preverifier, you are probably working
    on a platform with a case-insensitive file system, such as Windows. The
    <code>preverify</code> tool always unpacks the jars, so class files with
    similar lower-case and upper-case names overwrite each other. You can use
    ProGuard's <code>-dontusemixedcaseclassnames</code> option to work around
    this problem.
    <p>
    If the above doesn't help, there is probably a bug in the optimization step
    of ProGuard. Make sure you are using the latest version. You should be able
    to work around the problem by using the <code>-dontoptimize</code> option.
    You can check the bug database to see if it is a known problem (often with
    a fix). Otherwise, please report it, preferably with the simplest example
    on which you can find ProGuard to fail.</dd>

</dl>

Note that it is no longer necessary to use an external preverifier. With the
<code>-microedition</code> option, ProGuard will preverify the class files for
Java Micro Edition.
<p>

<a name="runtime">&nbsp;</a>
<h2>Problems at run-time</h2>

If ProGuard runs fine, but your processed application doesn't work, there
might be several reasons:

<dl>
<dt><a name="stacktraces"><b>Stack traces without class names or line numbers</b></a></dt>

<dd>If your stack traces don't contain any class names or lines numbers,
    even though you are keeping the proper attributes, make sure this debugging
    information is present in your compiled code to start with. Notably the Ant
    javac task has debugging information switched off by default.</dd>

<dt><a name="noclassdeffounderror"><b>NoClassDefFoundError</b></a></dt>

<dd>Your class path is probably incorrect. It should at least contain all
    library jars and, of course, your processed program jar.</dd>

<dt><a name="classnotfoundexception"><b>ClassNotFoundException</b></a></dt>

<dd>Your code is probably calling <code>Class.forName</code>, trying to create
    the missing class dynamically. ProGuard can only detect constant name
    arguments, like <code>Class.forName("mypackage.MyClass")</code>. For
    variable name arguments like <code>Class.forName(someClass)</code>, you
    have to keep all possible classes using the <code>-keep</code> option,
    e.g. "<code>-keep class mypackage.MyClass</code>" or "<code>-keep class *
    implements mypackage.MyInterface</code>".</dd>

<dt><a name="nosuchmethodexception"><b>NoSuchMethodException</b></a></dt>

<dd>Your code is probably calling something like
    <code>myClass.getMethod</code>, trying to find some method dynamically.
    Since ProGuard isn't detecting this (yet), you have to keep the missing
    method in using the <code>-keep</code> option, e.g. "<code>-keep class
    mypackage.MyClass { void myMethod(); }</code>".</dd>

<dt><a name="missingresourceexception"><b>MissingResourceException</b> or
    <b>NullPointerException</b></a></dt>

<dd>Your processed code may be unable to find some resource files. ProGuard
    currently simply copies resource files over from the input jars to the
    output jar. Their names and contents remain unchanged. If a class looks
    for a resource file in its directory, this will fail if the package name
    of the class has changed. You should then keep the class name, with the
    <code>-keepnames</code> option. Also note that directory entries in jar
    files aren't copied at all.</dd>

<dt><a name="invalidjarfile"><b>Invalid or corrupt jarfile</b></a></dt>

<dd>You are probably starting your application with the java option
    <code>-jar</code> instead of the option <code>-classpath</code>. The java
    virtual machine returns with this error message if your jar doesn't
    contain a manifest file (<code>META-INF/MANIFEST.MF</code>), if the
    manifest file doesn't specify a main class (<code>Main-Class:</code> ...),
    or if the jar doesn't contain this main class. You should then make sure
    that the input jar contains a valid manifest file to start with, that this
    manifest file is the one that is copied (the first manifest file that is
    encountered), and that the main class is kept in your configuration,</dd>

<dt><a name="invalidclassexception2"><b>InvalidClassException</b>,
    <b>class loading error</b>, or
    <b>verification error</b> (in Java Micro Edition)</a></dt>

<dd>If you get such an error in Java Micro Edition, you may have forgotten to
    specify the <code>-microedition</code> option, so the processed class
    files are preverified properly.</dd>

<dt><a name="failingmidlets"><b>Failing midlets</b> (in Java Micro Edition)</a></dt>

<dd>If your midlet simply won't start, you might try using the
    <code>-dontusemixedcaseclassnames</code> option. Even if it has been
    properly processed and then preverified on a case-sensitive file system,
    the device itself might not like the mixed-case class names. Notably, the
    Nokia N-Gage emulator works fine, but the actual device seems to exhibit
    this problem.</dd>

<dt><a name="securityexception"><b>SecurityException: SHA1 digest error</b></a></dt>

<dd>You may have forgotten to sign your program jar <i>after</i> having
    processed it with ProGuard.</dd>

<dt><a name="classcastexception"><b>ClassCastException: class not an enum</b></a></dt>

<dd>You are probably processing enumeration types and calling
    <code>EnumSet.allOf</code>. You should then make sure you're preserving
    the <code>values()</code> method of the enumeration type, as shown in the
    examples.</dd>

<dt><a name="arraystoreexception"><b>ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy</b></a></dt>

<dd>You are probably processing annotations involving enumerations. Again, you
    should make sure you're preserving the <code>values()</code> method of the
    enumeration type, as shown in the examples.</dd>

<dt><a name="nosuchfieldormethod"><b>Error: No Such Field or Method</b>,
    <b>Error verifying method</b> (in a Java Micro Edition emulator)</a></dt>

<dd>If you get such a message in a Motorola or Sony Ericsson phone emulator,
    it's because these emulators don't like packageless classes and/or
    overloaded fields and methods. You can work around it by not using the
    options <b>-repackageclasses ''</b> and <b>-overloadaggressively</b>. If
    you're using the JME WTK plugin, you can adapt the configuration
    <code>proguard/wtk/default.pro</code> that's inside the
    <code>proguard.jar</code>.</dd>

<dt><a name="compilererror"><b>CompilerError: duplicate addition</b></a></dt>

<dd>You are probably compiling or running some code that has been obfuscated
    with the <code>-overloadaggressively</code> option. This option triggers a
    bug in <code>sun.tools.java.MethodSet.add</code> in Sun's JDK 1.2.2, which
    is used for (dynamic) compilation. You should then avoid this option.</dd>

<dt><a name="classformaterror"><b>ClassFormatError: repetitive field name/signature</b></a></dt>

<dd>You are probably processing some code that has been obfuscated before with
    the <code>-overloadaggressively</code> option. You should then use the
    same option again in the second processing round.</dd>

<dt><a name="nosuchmethoderror"><b>NoSuchMethodError</b> or
    <b>AbstractMethodError</b></a></dt>

<dd>Again, you should make sure you're not writing your output class files to a
    directory on a platform with a case-insensitive file system, such as
    Windows. Please refer to the first item on this list for details.
    <p>
    Furthermore, you should check whether you have specified your program jars
    and library jars properly. Program classes can refer to library classes,
    but not the other way around.
    <p>
    If all of this seems ok, perhaps there's a bug in ProGuard (gasp!). If so,
    please report it, preferably with the simplest example on which you can
    find ProGuard to fail.</dd>

<dt><a name="verifyerror"><b>VerifyError</b></a></dt>

<dd>Verification errors when executing a program are almost certainly the
    result of a bug in the optimization step of ProGuard. Make sure you are
    using the latest version. You should be able to work around the problem by
    using the <code>-dontoptimize</code> option. You can check the bug database
    to see if it is a known problem (often with a fix). Otherwise, please
    report it, preferably with the simplest example on which you can find
    ProGuard to fail.</dd>

</dl>

<hr>
<address>
Copyright &copy; 2002-2007
<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
</address>
</body>
</html>
